Autocomplete, the menu and the element bound to.
Hi all
Having problems running some code based on one of the samples with a custom source so using an ajax request. Works up to the point when a value is selected. The input field is set with the value of the option rather than the label. This seems to happen in the menu widget when it sets self.element.val(item.value) which would work fine if the autocomplete was created on the select but it isn't in the sample. Its set on the input. If I change the code to create the autocomplete on the select then the UI is broken because the positioning of the menu is way off to the left. I've tried to change the styling (the menudocking stuff) but its not behaving for me. Any ideas welcome.
Heres my code. First the code behind...
- public partial class WebForm1 : System.Web.UI.Page
- {
- [Serializable]
- private class CustomObject
- {
- public String Name { get; set; }
- public Int32 Value { get; set; }
- }
- protected void Page_Load(object sender, EventArgs e)
- {
- }
- [WebMethod(EnableSession = true)]
- public static jsSearchResult getData()
- {
- List<CustomObject> list = new List<CustomObject>();
- CustomObject obj = new CustomObject() { Name = "Leeds", Value = 1 };
- list.Add(obj);
- obj = new CustomObject() { Name = "London", Value = 2 };
- list.Add(obj);
- obj = new CustomObject() { Name = "Birmingham", Value = 3 };
- list.Add(obj);
- jsSearchResult returnObject = new jsSearchResult()
- {
- Data = list,
- TotalCount = 4
- };
- return returnObject;
- }
- }
Now the markup:
- <meta charset="UTF-8" />
-
- <script type="text/javascript">
- (function($) {
- $.widget("ui.combobox", {
- _create: function() {
- var self = this;
- var select = this.element.hide();
- var u = this.options.url;
- var p = this.options.params;
- var m = this.options.mapper;
- var f = this.options.error;
- var pageObject = this.options.pageObject;
- var text = pageObject[this.options.propertyText];
- var value = pageObject[this.options.propertyValue];
- var propValueName = this.options.propertyValue;
- if (text && value) {
- // update the select
- var opts = { value: text };
- $.each(opts, function(val, text) {
- $(select).append($('<option></option>').val(val).html(text));
- });
- // update the input with the text of the returned item
- $(input).val(text);
- }
- var input = $("<input>")
- .insertAfter(select)
- .autocomplete({
- source: function(request, response) {
- // var matcher = new RegExp(request.term, "i");
- // response(select.children("option").map(function() {
- // var text = $(this).text();
- // if (!request.term || matcher.test(text))
- // return {
- // id: $(this).val(),
- // label: text.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"),
- // value: text
- // };
- // }));
- $.ajax({
- type: "POST",
- url: u,
- dataType: "json",
- data: p,
- contentType: "application/json; charset=utf-8",
- success: function(data) {
- if ($.isFunction(m)) {
- var selectcontent = m(data.d);
- response(selectcontent);
- select.empty();
- $.each(selectcontent, function(val, text) {
- $(select).append($('<option></option>').val(text.value).html(text.label));
- });
- }
- },
- error: f
- })
- },
- delay: 0,
- select: function(e, ui) {
- if (!ui.item) {
- // remove invalid value, as it didn't match anything
- $(this).val("");
- return false;
- }
- $(this).focus();
- select.val(ui.item.id);
- self._trigger("selected", null, {
- item: select.find("[value='" + ui.item.id + "']")
- });
-
- },
- minLength: 0
- })
- .addClass("ui-widget ui-widget-content ui-corner-left");
- $("<button> </button>")
- .insertAfter(input)
- .button({
- icons: {
- primary: "ui-icon-triangle-1-s"
- },
- label: '',
- text: false
- }).removeClass("ui-corner-all")
- .addClass("ui-corner-right ui-button-icon")
- .position({
- my: "left center",
- at: "right center",
- of: input,
- offset: "-1 0"
- }).css("top", "")
- .click(function() {
- // close if already visible
- if (input.autocomplete("widget").is(":visible")) {
- input.autocomplete("close");
- return;
- }
- // pass empty string as value to search for, displaying all results
- input.autocomplete("search", "");
- input.focus();
- });
- },
- options: { // initial values are stored in the widget's prototype
- url: '../WebForm1.aspx/getData',
- params: {},
- input: {},
- pageObject: {},
- propertyText: null,
- propertyValue: null,
- doSearchOnEmpty: true,
- dropdownData: null,
- menudocking: {
- menucorner: "right top",
- inputcorner: "right bottom",
- collision: "none"
- },
- mapper: function(data) {
- // This default mapper method is used if the response is successful.
- // It maps the elements for the option text and value. Below, the
- // item.Name & item.Value are the properties of an element in the
- // collection returned by the pageMethod so supply your own mapper if
- // your elements have a different property.
- return $.map(data.Data, function(item) {
- return {
- label: item.Name,
- value: item.Value
- }
- })
- },
- error: function(request, message, exception) {
- if (message == "error") {
- alert("The parameters to the the request are probably invalid.");
- }
- else {
- alert(message);
- }
- }
- }
- });
- })(jQuery);
- $(function() {
- $("select").combobox({
- url: '../WebForm1.aspx/getData',
- propertyText: 'DropdownText',
- propertyValue: 'DropdownValue'
- });
- });
- </script>
- <style>
- /* TODO shouldn't be necessary */
- .ui-button-icon-only .ui-button-text { padding: 0.35em; }
- .ui-autocomplete-input { padding: 0.48em 0 0.47em 0.45em; }
- </style>
-
- <div class="demo">
- <div class="ui-widget">
- <label>Your preferred programming language: </label>
- <select>
-
- </select>
- </div>
- <div class="ui-widget">
- <label>Your preferred programming language: </label>
- <select>
-
- </select>
- </div>
- </div><!-- End demo -->
- <div class="demo-description">
- <p>
- A custom widget built by composition of Autocomplete and Button. You can either type something into the field to get filtered suggestions based on your input, or use the button to get the full list of selections.
- </p>
- <p>
- The input is read from an existing select-element for progressive enhancement, passed to Autocomplete with a customized source-option.
- </p>
- </div><!-- End demo-description -->
Thanks
Matt